import { Cell } from '@antv/x6';

import { BaseNodeProps, NodeDataTypes } from '@/components/complex/BaseNode/define';
import { NODE_TYPE } from '@/constants/config';
import { useGraph } from '@/hooks/useGraph';
import { findParentVariables } from '@/utils/graph';

export const activeEdgeIdAtom = atom<string | null>({
  default: '',
  key: 'activeEdgeId'
});

const edgeDataAtom = atom<BaseNodeProps<NODE_TYPE.BASE_EDGE>>({
  default: {},
  key: 'edgeData'
});

export const useCurrentEdge = () => {
  const { graph, saveGraph } = useGraph();
  const [activeEdgeId, setActiveEdgeId] = useRecoilState(activeEdgeIdAtom);
  const [currentEdgeData, setCurrentEdgeData] = useRecoilState(edgeDataAtom);

  const parentPrivateVariables = findParentVariables(graph!, activeEdgeId!, 'private');
  const parentPublicVariables = findParentVariables(graph!, activeEdgeId!, 'public');

  const setEdgeData = useCallback(
    (data: BaseNodeProps<NODE_TYPE.BASE_EDGE>, options?: Cell.SetDataOptions) => {
      const cellData = graph?.getCellById(activeEdgeId!).getData();
      const nodeData = {
        ...cellData,
        ...data
      };
      graph?.getCellById(activeEdgeId!).setData(nodeData, { overwrite: true, ...options });
      setCurrentEdgeData(nodeData);
      saveGraph();
    },
    [activeEdgeId, graph, saveGraph, setCurrentEdgeData]
  );

  const getDataForEdge = useCallback(() => {
    return currentEdgeData.data as NodeDataTypes[NODE_TYPE.BASE_EDGE];
  }, [currentEdgeData]);

  const setDataForEdge = useCallback(
    (data: NodeDataTypes[NODE_TYPE.BASE_EDGE], options?: Cell.SetDataOptions) => {
      setEdgeData(
        {
          data: data as any
        },
        options
      );
    },
    [setEdgeData]
  );

  useEffect(() => {
    if (activeEdgeId && graph) {
      const data = graph.getCellById(activeEdgeId).getData() || {};
      setEdgeData(data);
    }
  }, [activeEdgeId, graph, setEdgeData]);

  return {
    setDataForEdge,
    getDataForEdge,
    setEdgeData,
    activeEdgeId,
    setActiveEdgeId,
    parentPrivateVariables,
    parentPublicVariables,
    currentEdgeData
  };
};
